/*
 * @Author: huangwei
 * @Date: 2021-06-10 09:19:19
 * @LastEditors: 黄威
 * @LastEditTime: 2022-03-11 09:31:53
 * @Description: cesium draw
 */
import * as Cesium from 'Cesium'
import { DRAGHOOKS, AbsDraw, ISimpleHandler } from './AbsDraw'

import newGraphic from '../bind-map/graphic'
import { cartesianToLL } from '../coordinate'
import { viewerPix2Coord } from '../view'

// 事件映射
const EventMapper = {
    lclick: Cesium.ScreenSpaceEventType.LEFT_CLICK,
    rclick: Cesium.ScreenSpaceEventType.RIGHT_CLICK,
    move: Cesium.ScreenSpaceEventType.MOUSE_MOVE,
    ldown: Cesium.ScreenSpaceEventType.LEFT_DOWN,
    lup: Cesium.ScreenSpaceEventType.LEFT_UP,
}

export default class CesiumDraw extends AbsDraw {
    _on(type, event) {
        if (!this._eventHandler) {
            this._eventHandler = new Cesium.ScreenSpaceEventHandler(
                this.map.canvas
            )
        }
        this._eventHandler.setInputAction(event, EventMapper[type])
    }

    _off(type, event) {
        if (!this._eventHandler) return
        this._eventHandler.removeInputAction(EventMapper[type])

        // 尝试销毁
        if (
            this._eventHandler &&
            this._eventHandler._inputEvents &&
            Object.keys(this._eventHandler._inputEvents).length === 0
        ) {
            this._eventHandler.destroy()
            this._eventHandler = undefined
        }
    }

    _evtToCoord(evt) {
        const pos = evt.position || evt.endPosition
        const viewer = this.map

        return viewerPix2Coord(
            viewer,
            pos,
            this.options ? this.options.pickScean : false
        )
    }

    _setDragAble(flag) {
        this.map.scene.screenSpaceCameraController.enableRotate = !!flag
        this.map.scene.screenSpaceCameraController.enableTranslate = !!flag
    }
}

/* ********************  目前支持的一些方法 ********************** */
// 点
class C3PointHandler extends ISimpleHandler {
    MaxLen = 1

    _newGraphic() {
        return newGraphic('Point', true)
    }
}

// 图标
class C3MarkerHandler extends C3PointHandler {
    _newGraphic() {
        return newGraphic('Marker', true)
    }
}

// 线
class C3PolylineHandler extends ISimpleHandler {
    MinLen = 2

    get _guideStyle() {
        return {
            ...this.style,
            dashArray: [8, 16],
            fillOpacity: 0.1,
            interactive: false,
        }
    }

    _newGraphic(dynamic = false) {
        return newGraphic('Polyline', true, dynamic)
    }

    _newGuide() {
        return this._newGraphic(true)
            .setStyle(this._guideStyle)
            .addTo(this.target)
    }
    _updateGuide(coord) {
        if (this.coords.length) {
            this._guideG.setCoords([this.coords[this.coords.length - 1], coord])
        }
    }
}

// 面
class C3PolygonHandler extends C3PolylineHandler {
    MinLen = 3

    _newGraphic(dynamic = false) {
        return newGraphic('Polygon', true, dynamic)
    }

    _updateGuide(coord) {
        if (this.coords.length) {
            const coords = []

            coords.push(this.coords[this.coords.length - 1])
            coords.push(coord)

            if (this.coords.length >= 2) {
                coords.push(this.coords[0])
            }

            this._guideG.setCoords(coords)
        }
    }
}

class C3DragHandler extends C3PolygonHandler {
    MinLen = 2
    MaxLen = 2

    hooks = DRAGHOOKS
}

// 矩形
class C3RectangleHandler extends C3DragHandler {
    _newGraphic(dynamic = false) {
        return newGraphic('Rectangle', true, dynamic)
    }

    _updateGuide(coord) {
        if (this.coords.length) {
            this._guideG.setCoords([this.coords[0], coord])
        }
    }
}

// 圆
class C3CircleHandler extends C3DragHandler {
    _newGraphic(dynamic = false) {
        return newGraphic('Circle', true, dynamic)
    }

    _updateGuide(coord) {
        if (this.coords.length) {
            this._guideG.setCoords([this.coords[0], coord])
        }
    }
}

CesiumDraw.modes = {
    Point: C3PointHandler,
    Marker: C3MarkerHandler,
    Polyline: C3PolylineHandler,
    Polygon: C3PolygonHandler,
    Rectangle: C3RectangleHandler,
    Circle: C3CircleHandler,
}
